home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1995, Russell Lang. All rights reserved.
-
- This file is part of GSview.
-
- This program is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the GSview Free Public Licence
- (the "Licence") for full details.
-
- Every copy of GSview must include a copy of the Licence, normally in a
- plain ASCII text file named LICENCE. The Licence grants you the right
- to copy, modify and redistribute GSview, but only under certain conditions
- described in the Licence. Among other things, the Licence requires that
- the copyright notice and this notice be preserved on all copies.
- */
-
- /* gsv16spl.c */
- /* 16-bit access to print spooler from Win32s */
- /* by Russell Lang */
- /* 1995-11-10 */
-
- /*
- * GSview and Ghostscript produce printer specific output
- * which must be given to the print spooler.
- * Under Win16, the APIs OpenJob, WriteSpool etc. are used
- * Under Win32 and Windows 95/NT, the APIs OpenPrinter, WritePrinter etc.
- * are used.
- * Under Win32s, the 16-bit spooler APIs are not available, and the
- * 32-bit spooler APIs are not implemented.
- * This purpose of this application is to provide a means for the Win32s
- * versions of GSview and Ghostscript to send output to the 16-bit spooler.
- */
-
- /*
- * Usage: gsv16spl hwnd
- * hwnd is the window handle of the program starting gsv16spl
- *
- * hwnd will be sent a WM_USER+1=WM_GSV16SPL message with the window
- * handle of gsv16spl in the lParam.
- * gsv16spl is then called using SendMessage with the handle of
- * a global shareable memory block in lParam.
- * The first SendMessage should have the null terminated name of the
- * printer port in this memory block.
- * Subsequent memory blocks contain data to be sent to that port.
- * The memory block contains a length count in the first WORD,
- * followed by the actual data.
- * A length count of 0 indicates EOF. This will cause gsv16spl
- * to close the print job and exit.
- * A length count of -1 indicates an error. gsv16spl will abort
- * the print job and exit.
- */
-
-
- #define STRICT
- #include <windows.h>
- /* #include <string.h> */
- #include <stdlib.h>
-
- /* documented in Device Driver Adaptation Guide */
- /* Prototypes taken from print.h */
- DECLARE_HANDLE(HPJOB);
-
- HPJOB WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
- int WINAPI StartSpoolPage(HPJOB);
- int WINAPI EndSpoolPage(HPJOB);
- int WINAPI WriteSpool(HPJOB, LPSTR, int);
- int WINAPI CloseJob(HPJOB);
- int WINAPI DeleteJob(HPJOB, int);
- int WINAPI WriteDialog(HPJOB, LPSTR, int);
- int WINAPI DeleteSpoolPage(HPJOB);
-
- HPJOB hJob;
- unsigned long bytes_written;
- char portname[64];
- POINT char_size;
- HWND hwndspl;
- HWND hwndnotify; /* window handle of caller */
- HICON hiconspl;
- HINSTANCE phInstance;
-
- #define ID_GSV16SPL 42
- #define IDC_ABOUT 200
- #define WM_GSV16SPL WM_USER+1
- #define WINDOWWIDTH (36*char_size.x)
- #define WINDOWHEIGHT ( 5*char_size.y)
- char szAppName[] = "GS Win32s/Win16 spooler";
- char debug_str[64];
-
- void
- draw_text(HWND hwnd, HDC hdc)
- {
- char buf[256];
- RECT rect;
- int x, y;
- GetClientRect(hwnd, &rect);
- x = 3 * char_size.x + 32;
- y = (rect.bottom - rect.left - char_size.y) / 2;
-
- SetTextAlign(hdc, TA_LEFT | TA_TOP);
- if (hwndnotify) {
- wsprintf(buf, "%lu bytes written to %s", bytes_written, (LPSTR)portname);
- TextOut(hdc, x, y, buf, lstrlen(buf));
- if (debug_str)
- TextOut(hdc, x, y + char_size.y, debug_str, lstrlen(debug_str));
- }
- else {
- lstrcpy(buf, "Playing Russian Roulette are we?");
- TextOut(hdc, x, y - char_size.y, buf, lstrlen(buf));
- lstrcpy(buf, "GSV16SPL is called automatically");
- TextOut(hdc, x, y, buf, lstrlen(buf));
- lstrcpy(buf, "from GSview or Ghostscript.");
- TextOut(hdc, x, y + char_size.y, buf, lstrlen(buf));
- }
- }
-
- int
- open_printer(LPSTR port)
- {
- lstrcpy(portname, port);
- hJob = OpenJob(port, szAppName, (HDC)NULL);
- switch ((int)hJob) {
- case SP_APPABORT:
- case SP_ERROR:
- case SP_OUTOFDISK:
- case SP_OUTOFMEMORY:
- case SP_USERABORT:
- hJob = NULL;
- lstrcpy(debug_str, "OpenJob failed");
- return FALSE;
- }
- if (StartSpoolPage(hJob) < 0) {
- lstrcpy(debug_str, "StartSpoolPage failed");
- DeleteJob(hJob, 0);
- hJob = NULL;
- return FALSE;
- }
- return TRUE; /* OK */
- }
-
- int
- close_printer(void)
- {
- if (hJob == (HPJOB)NULL)
- return FALSE;
- EndSpoolPage(hJob);
- CloseJob(hJob);
- hJob = NULL;
- return TRUE;
- }
-
- int
- abort_printer(void)
- {
- if (hJob == (HPJOB)NULL)
- return FALSE;
- EndSpoolPage(hJob);
- DeleteJob(hJob, 0);
- hJob = NULL;
- return TRUE;
- }
-
- int
- write_printer(LPSTR data, WORD length)
- {
- if (hJob == (HPJOB)NULL)
- return FALSE;
- if (WriteSpool(hJob, data, length) < 0) {
- lstrcpy(debug_str, "WriteSpool failed");
- abort_printer();
- return FALSE;
- }
- return TRUE;
- }
-
- int
- process_block(HGLOBAL hmem)
- {
- LPBYTE lpbyte;
- WORD length;
- int rc;
- if (hmem == (HGLOBAL)NULL) {
- lstrcpy(debug_str, "hglobal is null");
- return FALSE;
- }
- lpbyte = GlobalLock(hmem);
- if (lpbyte == (LPBYTE)NULL) {
- lstrcpy(debug_str, "Couldn't lock hglobal");
- return FALSE;
- }
- length = *(LPWORD)lpbyte;
- if (length == 0) {
- /* EOF */
- lstrcpy(debug_str, "Got EOF");
- GlobalUnlock(hmem);
- PostQuitMessage(0);
- return close_printer();
- }
- else if (length == 0xffff) {
- /* Abort */
- lstrcpy(debug_str, "Got Abort");
- GlobalUnlock(hmem);
- PostQuitMessage(0);
- return abort_printer();
- }
-
- if (hJob) {
- HDC hdc;
- rc = write_printer((LPSTR)(lpbyte+2), length);
- bytes_written += length;
- hdc = GetDC(hwndspl);
- draw_text(hwndspl, hdc);
- ReleaseDC(hwndspl, hdc);
- }
- else {
- rc = open_printer((LPSTR)(lpbyte+2));
- }
- GlobalUnlock(hmem);
- return rc;
- }
-
- /* copyright dialog box */
- BOOL CALLBACK _export
- AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch(message) {
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDOK:
- EndDialog(hDlg, TRUE);
- return(TRUE);
- default:
- return(FALSE);
- }
- default:
- return(FALSE);
- }
- }
-
- void
- show_about(void)
- {
- DLGPROC lpProcAbout;
- lpProcAbout = (DLGPROC)MakeProcInstance((FARPROC)AboutDlgProc, phInstance);
- DialogBoxParam( phInstance, "AboutDlgBox", hwndspl, lpProcAbout, (LPARAM)NULL);
- FreeProcInstance((FARPROC)lpProcAbout);
- }
-
-
- /* Window Procedure */
- LRESULT CALLBACK _export
- WndSplProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HMENU hmenu;
- PAINTSTRUCT ps;
- HDC hdc;
- RECT rect;
- switch(message) {
- case WM_GSV16SPL:
- /* we have been called using SendMessage so we */
- /* must not do anything that requires the message queue */
- return process_block((HGLOBAL)lParam);
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- draw_text(hwnd, hdc);
- GetClientRect(hwnd, &rect);
- DrawIcon(hdc, char_size.x, (rect.bottom-rect.top-32)/2, hiconspl);
- EndPaint(hwnd, &ps);
- return 0;
- case WM_CREATE:
- hmenu = GetSystemMenu(hwnd,FALSE);
- EnableMenuItem(hmenu, SC_SIZE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(hmenu, SC_MAXIMIZE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
- AppendMenu(hmenu, MF_ENABLED, IDC_ABOUT, "&About");
- break;
- /* case WM_CLOSE: */
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- case WM_SYSCOMMAND:
- switch(LOWORD(wParam)) {
- case IDC_ABOUT:
- show_about();
- return 0;
- }
- break;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
-
-
- void
- init_window(void)
- {
- int i;
- WNDCLASS wndclass;
- HDC hdc;
- TEXTMETRIC tm;
- HFONT hfont;
-
- /* register the window class */
- wndclass.style = 0;
- wndclass.lpfnWndProc = WndSplProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = phInstance;
- wndclass.hIcon = hiconspl = LoadIcon(phInstance, MAKEINTRESOURCE(ID_GSV16SPL));
- wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
- wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- RegisterClass(&wndclass);
-
- hdc = GetDC(NULL); /* desktop */
- hfont = GetStockObject(SYSTEM_FIXED_FONT);
- SelectObject(hdc, hfont);
- GetTextMetrics(hdc, (LPTEXTMETRIC)&tm);
- ReleaseDC(NULL, hdc);
- char_size.x = tm.tmAveCharWidth;
- char_size.y = tm.tmHeight;
-
- hwndspl = CreateWindow(szAppName, (LPSTR)szAppName,
- WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
- /*
- CW_USEDEFAULT, CW_USEDEFAULT,
- */
- 0,0,
- WINDOWWIDTH, WINDOWHEIGHT,
- NULL, NULL, phInstance, (void FAR *)NULL);
-
- return;
- }
-
- int PASCAL
- WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
- {
- MSG msg;
- phInstance = hInstance;
-
- /* find out window handle of caller */
- if (lpszCmdLine[0] != '\0') {
- char buf[64];
- lstrcpyn(buf, lpszCmdLine, sizeof(buf)-1);
- hwndnotify = (HWND)atoi(buf);
- }
- else {
- hwndnotify = (HWND)NULL;
- }
-
- init_window();
- ShowWindow(hwndspl, cmdShow);
-
- /* notify caller about our window handle */
- if (hwndnotify)
- SendMessage(hwndnotify, WM_GSV16SPL, 0, (LPARAM)hwndspl);
-
- while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- DestroyWindow(hwndspl);
- return 0;
- }
-
-